package com.redoor.app.stake.auth.service.impl;

import com.redoor.app.stake.auth.commons.DatabaseServiceStatus;
import com.redoor.app.stake.auth.dao.BaseUserMapper;
import com.redoor.app.stake.auth.dao.BaseUserOrgMapper;
import com.redoor.app.stake.auth.dao.BaseUserRoleMapper;
import com.redoor.app.stake.auth.model.*;
import com.redoor.app.stake.auth.model.serviceModel.BaseUserServiceBean;
import com.redoor.app.stake.auth.model.serviceModel.LoginUserBean;
import com.redoor.app.stake.auth.service.BaseRoleService;
import com.redoor.app.stake.auth.service.BaseUserService;
import com.redoor.app.stake.common.utils.UUIDTool;
import com.redoornetwork.framework.mybatis.service.AbstractService;
import io.swagger.annotations.ApiModelProperty;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.session.Session;
import org.crazycake.shiro.RedisManager;
import org.crazycake.shiro.RedisSessionDAO;
import org.crazycake.shiro.SerializeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import sunbox.core.hsf.api.SysManageService;
import sunbox.core.hsf.vo.OperatorItem;
import sunbox.core.vo.api.OpenAPIResponse;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * Created by wangjunlei on 2018-02-07 15:19:13.
 */
@Transactional
@Service(value = "BaseUserService")
public class BaseUserServiceImpl extends AbstractService<BaseUser, String> implements BaseUserService {

    @Autowired
    private BaseUserMapper baseUserMapper;

    @Autowired
    private BaseUserOrgMapper baseUserOrgMapper;

    @Autowired
    private BaseUserRoleMapper baseUserRoleMapper;

    @Autowired
    private RedisSessionDAO redisSessionDAO;

    @Autowired
    private SysManageService sysManageService;

    @Autowired
    private BaseRoleService baseRoleService;

    private final Logger logger = LoggerFactory.getLogger(BaseUserServiceImpl.class);

    @Override
    public LoginUserBean findByUsername(String username) {
        return baseUserMapper.qryLoginUser(username);
    }

    @Override
    public BaseUserView buildUserinfo(String userToken) {
        /*****begin Description:Change [StringUtils.isEmpty] to [.isBlank]  author:zhangMumu edit 2018/4/14 0014 14:04*****/
        if(StringUtils.isEmpty(userToken)){
            logger.error("BaseUserServiceImpl_buildUserinfo_params is blank");
            return null ;
        }
        /*****end Description:Change [StringUtils.isEmpty] to [.isBlank]  author:zhangMumu edit 2018/4/14 0014 14:04*****/

        /*get userInfo from OpenApi by userToken*/
        OpenAPIResponse resp = sysManageService.getLoginCustomer(userToken) ;

        /*****begin Description:Increase null-judgement  author:zhangMumu add 2018/4/14 0014 14:11*****/
        if (null == resp || null == resp.getData()){
            return null;
        }
        /*****end Description:Increase null-judgement  author:zhangMumu add 2018/4/14 0014 14:11*****/

        OperatorItem operatorItem = (OperatorItem)resp.getData() ;
        /*add||update userInfo to the dataBase*/
        addOperatorItemToUser(operatorItem);

        BaseUserCriteria criteria = new BaseUserCriteria();
        criteria.setLoginName(operatorItem.getUserName());
        List<BaseUserView> users = baseUserMapper.getByParams(criteria);
        BaseUserView userView = (users!=null && users.size()>0) ? users.get(0) : null;
        return userView;
    }

    @Override
    public List<String> queryAllPerms(String uuid) {
        return baseUserMapper.queryAllPerms(uuid);
    }

    @Override
    public LoginUserBean getShiroUser(String sessionid) {
        if(StringUtils.isEmpty(sessionid)){
            try{
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                sessionid = request.getSession().getId();
            } catch (Exception ex){
                return null;
            }
        }
        String userkey = redisSessionDAO.getKeyPrefix()+sessionid;
        RedisManager redisManager = redisSessionDAO.getRedisManager();
        byte[] value = redisManager.get(userkey.getBytes());
        if(value!=null){
            Session shiroSession = (Session) SerializeUtils.deserialize(value);
            LoginUserBean user = (LoginUserBean)shiroSession.getAttribute("userSession");
            return user;
        }
        return null;
    }

    @Override
    public String getShiroUserUuid() {
        BaseUser user = getShiroUser(null);
        if(user != null ) {
            return user.getUuid();
        }
        return "";
    }

    @Override
    public int updateByUserUuidAndPassword(BaseUserServiceBean baseUserActon) {

        return this.baseUserMapper.updateByUserUuidAndPassword(baseUserActon);
    }

    @Override
    public int insertBaseUser(BaseUserServiceBean baseUserAction) {
        //插入数据到用户表
        int status = this.baseUserMapper.insert(baseUserAction);
        status += this.insertUserRole(baseUserAction);
        return status;
    }

    @Override
    public List<BaseUser> qryUser(BaseUser baseUser) {
        return this.baseUserMapper.qryUser(baseUser);
    }

    @Override
    public int revicePassword(String uuid) {
        BaseUser user = this.baseUserMapper.selectByPrimaryKey(uuid);
        BaseUser loginUser = this.getShiroUser(null);
        BaseUserServiceBean action = new BaseUserServiceBean();
        action.setOldPassword(user.getPassword());
        action.setUserid(user.getUserid());
        action.setUpdatedat(new Date());
        action.setUpdateruuid(loginUser.getUuid());
        // TODO 未进行加密处理
        action.setPassword(user.getLoginname());
       return this.baseUserMapper.updateByUserUuidAndPassword(action);
    }

    @Override
    public Integer updateStatusByUuid(String uuid) {
        BaseUser loginUser = this.getShiroUser(null);
        BaseUser trem = new BaseUser();
        trem.setUuid(uuid);
        trem.setUpdateruuid(loginUser.getUuid());
        trem.setUpdatedat(new Date());
        trem.setStatus(Integer.valueOf(DatabaseServiceStatus.SERVICE_DEL_STATUS.getCode()));
        //修改用户表状态
        int status = this.baseUserMapper.updateByPrimaryKeySelective(trem);
        BaseUserRole baseUserRole = new BaseUserRole();
        baseUserRole.setUseruuid(uuid);
        //删除用户角色中间表数据
        status += this.baseUserRoleMapper.delete(baseUserRole);
        return status;
    }

    @Override
    public int updateByUuid(BaseUserServiceBean baseUserAction) {
        int status = this.baseUserMapper.updateByPrimaryKeySelective(baseUserAction);
       if(status == 0){
           return 0;
       }
        BaseUserRole userRole = new BaseUserRole();
        userRole.setUseruuid(baseUserAction.getUuid());
       status += this.baseUserRoleMapper.delete(userRole);
       status += this.insertUserRole(baseUserAction);
       return status;
    }

    @Override
    public void addOperatorItemToUser(OperatorItem op) {
        // 科东用户 添加标志位
        boolean addFlag = false;

        BaseUser kedongBean = findByUsername(op.getUserName());
        // 没有查询到，说明需要在用户表中添加一条数据
        if (kedongBean == null) {
            addFlag = true;
            kedongBean = new BaseUser();
            kedongBean.setUuid(UUIDTool.getUUID());
            kedongBean.setCreatedat(new Date());
        }

        // 登录用户名
        kedongBean.setUserid(op.getId()+"");
        kedongBean.setLoginname(op.getUserName());
        kedongBean.setNickname(op.getOuName());
        kedongBean.setFullname(op.getRealName());
        kedongBean.setStatus(1000);
        kedongBean.setPassword(op.getPassword());
        kedongBean.setPhone(op.getPhone());
        kedongBean.setUpdatedat(new Date());

        // 将创建的科东用户保存到数据库中
        if (addFlag)  {
            save(kedongBean);

            BaseUserOrg uo = new BaseUserOrg();
            uo.setUuid(UUIDTool.getUUID());
            uo.setUseruuid(kedongBean.getUuid());
            uo.setOuCode(op.getOuCode());

            baseUserOrgMapper.insert(uo);
        } else {
            updateBySelective(kedongBean);
        }
    }

    /**
     * 向用户权限表插入数据
     * @Author zhangYiHang
     * @Date 2018/3/10 20:47
     */
        private int insertUserRole(BaseUserServiceBean baseUserAction){
            try {
                if(baseUserAction.getRoleUuids() != null && baseUserAction.getRoleUuids().trim().length() != 0){
                    String[] roleUuids =baseUserAction.getRoleUuids().split(",");
                    for (String roleUuid: roleUuids ) {
                        BaseUserRole insertUserRole = new BaseUserRole();
                        insertUserRole.setUuid(UUID.randomUUID().toString());
                        insertUserRole.setUseruuid(baseUserAction.getUuid());
                        insertUserRole.setRoleuuid(roleUuid);
                        //循环插入数据到用户角色表中
                        this.baseUserRoleMapper.insert(insertUserRole);
                    }
                }
                return 1;
            } catch (Exception e) {
                logger.error("用户权限信息添加失败");
                return 0;
            }
        };

        @Override
        public List<String> districtPermission() {
            /*没有登陆人则返回 null 有所有权限*/
            LoginUserBean shiroUser = this.getShiroUser(null);
            if (null == shiroUser){
                return null;
            }
            /*判断登陆人是否是管理员,是管理员有所有权限*/
            if (baseRoleService.qrySupperByLoginUseruuid()){
                return null;
            }

            String oucode = shiroUser.getOucode();
            /*当前登陆人没有组织结构, 有所有权限*/
            if (StringUtils.isBlank(oucode)){
                return null;
            }
            String[] ouCodes = oucode.split(",");
            /*当前登陆人没有组织结构, 有所有权限*/
            if (ArrayUtils.isEmpty(ouCodes)){
                return null;
            }

            for(int i = 0; i < ouCodes.length ; i ++){
                String oneOuCode = ouCodes[i];
                /*登陆人所属组织机构只要有等于3的,有所有权限*/
                if ("3".equalsIgnoreCase(oneOuCode)){
                    return null;
                /*组织机构为省或地市,返回该组织机构*/
                }else if(7 == oneOuCode.length() || 10 == oneOuCode.length()){
                    ouCodes[i] = oneOuCode;
                /*组织机构为部门级别,返回该组织机构的地市级别组织机构*/
                }else if (13 == oneOuCode.length()){
                    ouCodes[i] = oneOuCode.substring(0,10);
                }
            }
            return Arrays.asList(ouCodes);
        }

}
